package servlets;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import common.FilePathHelper;
import common.XMLParserUtil;

import bean.ITemplate;

import factory.TemplateFactory;

/**
 * Servlet implementation class BAI_generator
 */
public class BAIGenerator extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	private static TemplateFactory templateFactory = TemplateFactory
			.getInstance();// the TemplateFactory singleton

	/*
	 * the template set, all the instances contained in this set are created via
	 * reflection of Java by reading the Template class names from BAI.xml file
	 * and modifier "static" indicates that all the thread access this servlet
	 * has the only copy of templateSet all the instances will be created in
	 * method init() by TemplateFactory
	 */
	private static Set<ITemplate> templateSet = Collections
			.synchronizedSet(new HashSet<ITemplate>());
	private static String headRawContent; // the common raw head content
	private static String footRawContent; // the common raw foot content
	private final static String filenameRequestURL = "http://tools/datools/srishivananda/cgi-bin/Query.cgi?ConnectionType=ConfigHosts;Env=StagingDB;txtHost=;Host=PgwHost;Characterset=;Sql=select+PG_FILE_ID_SEQ.NEXTVAL+from+DUAL;Action=Query";
	
    /**
     * Default constructor. 
     */
    public BAIGenerator() {
    	super();
    }
    
    
    /**
	 * @see Servlet#init(ServletConfig)
	 */
	public void init(ServletConfig config) throws ServletException {
		
		// read the BAI.xml file and split following info(for the structure of
		// the XML file, refer to BAI.xml):
		// template type, all attributes, plain text content
		XMLParserUtil xmlParser = XMLParserUtil.getInstance();
//		String xmlPath = config.getServletContext().getRealPath("/")
//				+ "BAI.xml";
		String xmlPath = FilePathHelper.getXmlFilePath();
		
//		System.out.println(xmlPath);
		Document doc = xmlParser.getDocument(xmlPath);// if the path of the xml
														// file is legal?
		// First get the root element templates
		Element root = xmlParser.getRootElem(doc);

		Node headNode = xmlParser.getElements(root, "head").item(0);
		Node footNode = xmlParser.getElements(root, "footer").item(0);
		headRawContent = (xmlParser.getChildNodeByNodeType(headNode,
				Node.CDATA_SECTION_NODE).get(0)).getTextContent();
		footRawContent = (xmlParser.getChildNodeByNodeType(footNode,      
				Node.CDATA_SECTION_NODE).get(0)).getTextContent();

		// Then get all template node list
		NodeList nodeList = xmlParser.getElements(root, "template");// all
																	// template
																	// nodes
																	// list

		Node templateNode = null;// Current template node that contains the info
									// to create a TemplateX object
		String type = null;// the type of the Template
		String rawContent = null;// the raw content of the template
		for (int i = 0; i < nodeList.getLength(); i++) {
			templateNode = nodeList.item(i);
			/*
			 * use current templateNode object to create a TemplateX obejct, and
			 * add it to the templateSet
			 */
			type = xmlParser.getAttrValByName(templateNode, "type");

			// System.out.println();
			NodeList contentNodeList = (xmlParser.getChildElemNodeByName(
					templateNode, "content")).getChildNodes();
			for (int j = 0; j < contentNodeList.getLength(); j++) {
				if (contentNodeList.item(j).getNodeType() == Node.CDATA_SECTION_NODE) {
					rawContent = contentNodeList.item(j).getTextContent();
					break;
				}
			} // inner for ends

			/*
			 * Following try to set the attributes ArrayList
			 */
			Node attrsNode = xmlParser.getChildElemNodeByName(templateNode,
					"attributes");// attributes element node
			ArrayList<Node> list = xmlParser.getChildElementNodesByName(
					attrsNode, "attribute");// the chid attribute node of
											// attributes node
			ArrayList<String> attrNames = new ArrayList<String>();// all the
																	// attribute
																	// names
																	// contained
																	// in the
																	// template
			Iterator<Node> iter = list.iterator();
			while (iter.hasNext()) {
				attrNames.add(iter.next().getTextContent());
			} // inner while ends

			/*
			 * Following use templateFactory to create TemplateX object and add
			 * it to the templateSet
			 */
			ITemplate templateObj = templateFactory.createTemplate(type,
					attrNames, rawContent);
			templateSet.add(templateObj);
			// System.out.println("Create a template object, its raw content is as follow: ");
			// System.out.println(templateObj.getContent());

			// System.out.println("DispatchServlet template content: start");
			// System.out.println(templateObj.getContent());
			// System.out.println("DispatchServlet template content: end");
		}// outer for ends

	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		RequestDispatcher dispatcher = request.getRequestDispatcher("savefile.jsp");
		dispatcher.forward(request, response);
	}
	
	public static Set<ITemplate> getTemplates() {
		return templateSet;
	}

	public static String getHeadRawContent() {
		return headRawContent;
	}

	public static String getFootRawContent() {
		return footRawContent;
	}
	
	public static String getFileNameRequestURL() {
		return filenameRequestURL;
	}

}
